package action;

import character.CharacterCombatControl;
import character.MyCharacter;
import character.MyCharacterControl;
import com.jme3.math.FastMath;

public abstract class Action {
    protected MyCharacter character;
    protected MyCharacterControl charControl;
    protected int ticksRemaining;
    private int totalTicks;
    protected boolean started = false, completed = false, offTurnAction = false;
    
    @Deprecated
    protected Action() {}
    
    public Action(MyCharacter character, int totalTicks) {
        this.character = character;
        init(totalTicks);
    }
    
    public Action(boolean offTurnAction, MyCharacter character, int totalTicks) {
        this.offTurnAction = offTurnAction;
        this.character = character;
        init(totalTicks);
    }
    
    private void init(int totalTicks) {
        charControl = character.getControl(MyCharacterControl.class);
        setTotalTicks(totalTicks);
    }
    
    /** Returns true if the tick was successful (i.e. other listeners should also tick) */
    public boolean tickAction() {
        boolean tickSuccessful = true;
        if(!started)
            startAction();
        
        if(started) {
            tickSuccessful = tick();
            if(charControl instanceof CharacterCombatControl && !offTurnAction)
                ((CharacterCombatControl)charControl).addTicksUsed(1);
            if(getTotalTicks() != -1) //means this action is not limited by ticks (such as a roaming move)
                ticksRemaining--;
        }
        
        if(ticksRemaining == 0 && !completed) {
	    completeAction();
        }
        
        return tickSuccessful;
    }
    
    protected void startAction() {
	started = true;
	start();
    }

    protected void completeAction() {
	completed = true;
	complete();
    }

    public void abortAction() {
	completed = true;
        abort();
    }
    
    protected abstract void start();
    /** Returns true if the tick was successful (i.e. other listeners should also tick) */
    protected abstract boolean tick();
    protected abstract void complete();
    protected abstract void abort();
    /** Triggered when an action must be paused between character turns. */
    public abstract void pause();
    /** Triggered when an action is resumed after being paused between character turns. */
    public abstract void unpause();
    
    public int getTicksRemaining() {
	return ticksRemaining;
    }

    public int getTotalTicks() {
        return totalTicks;
    }
    public void setTotalTicks(int totalTicks) {
        this.totalTicks = Math.round(FastMath.ceil(totalTicks * character.getCharacterStats().getActionSpeedModifier()));
        ticksRemaining = this.totalTicks;
    }
    public boolean isOffTurnAction() {
        return offTurnAction;
    }
    public boolean isStarted() {
	return started;
    }
    public boolean isCompleted() {
	return completed;
    }
}
